package com.xwy.usercenter.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xwy.usercenter.common.BaseResponse;
import com.xwy.usercenter.common.ErrorCode;
import com.xwy.usercenter.common.ResultUtils;
import com.xwy.usercenter.exception.BusinessException;
import com.xwy.usercenter.model.Team;
import com.xwy.usercenter.model.User;
import com.xwy.usercenter.model.UserTeam;
import com.xwy.usercenter.model.dto.TeamQuery;
import com.xwy.usercenter.model.request.TeamAddRequest;
import com.xwy.usercenter.model.request.TeamJoinRequest;
import com.xwy.usercenter.model.request.TeamQuitRequest;
import com.xwy.usercenter.model.request.TeamUpdateRequest;
import com.xwy.usercenter.model.vo.TeamUserVO;
import com.xwy.usercenter.service.TeamService;
import com.xwy.usercenter.service.UserService;
import com.xwy.usercenter.service.UserTeamService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/team")
@CrossOrigin(origins = {"http://localhost:3000"})   //配置处理跨域问题，灵活配置哪个方法可以跨域哪个不行
@Slf4j
public class TeamController {

    @Resource
    private TeamService teamService;

    @Resource
    private UserTeamService userTeamService;

    @Resource
    private UserService userService;

    @PostMapping("/add")
    public BaseResponse<Long> addTeam(@RequestBody TeamAddRequest teamAddRequest, HttpServletRequest request){
        //1. 请求参数是否为空？
        if (teamAddRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Team team = new Team();
        BeanUtil.copyProperties(teamAddRequest, team);
        //2. 是否登录，未登录不允许创建
        User loginUser = userService.getLoginUser(request);
        Long teamId = teamService.addTeam(team, loginUser);
        return ResultUtils.success(teamId);
    }

    @DeleteMapping("/delete")
    public BaseResponse<Boolean> deleteTeam(@RequestBody Long teamId, HttpServletRequest request){
        if (teamId <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        boolean result = teamService.removeTeam(teamId, loginUser);
        if (!result){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除失败");
        }
        return ResultUtils.success(result);
    }

    @PostMapping("/update")
    public BaseResponse<Boolean> updateTeam(@RequestBody TeamUpdateRequest teamUpdateRequest, HttpServletRequest request){
        if (teamUpdateRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        Boolean result = teamService.updateTeam(teamUpdateRequest, loginUser);
        if (!result){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新失败");
        }
        return ResultUtils.success(result);
    }

    @GetMapping("/get")
    public BaseResponse<Team> getTeam(Long teamId){
        if (teamId <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Team team = teamService.getById(teamId);
        if (team == null){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "查找失败");
        }
        return ResultUtils.success(team);
    }

    @GetMapping("/list")
    public BaseResponse<List<TeamUserVO>> listTeam(TeamQuery teamQuery,HttpServletRequest request){
        if (teamQuery == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean isAdmin = userService.isAdmin(request);
        //查询出队伍列表
        List<TeamUserVO> list = teamService.listTeam(teamQuery, isAdmin);
        //获取已查询出的队伍列表id
        final List<Long> teamIdList = list.stream().map(TeamUserVO::getId).collect(Collectors.toList());
        LambdaQueryWrapper<UserTeam> queryWrapper = new LambdaQueryWrapper<>();
        //使用try...catch原因：因为在getLoginUser()中判断如果未登录是要抛出异常的，
        //但是该接口在未登录的情况下仍允许查询。后面代码主要目的是为了给前端提供一个标志，
        //用来选择性的显示“退出队伍”“加入队伍”等按钮，未登录和已登录的状态同时适用，如果
        //用户这时没有登录，则getLoginUser()会抛异常，与我们允许未登录查询冲突，所以不想
        //异常再抛出，就用try...catch捕获
        try {
            User loginUser = userService.getLoginUser(request);
            //在数据库中查询当前登录者是否加入查询出的队伍中
            queryWrapper.eq(UserTeam::getUserId, loginUser.getId())
                    .in(UserTeam::getTeamId, teamIdList);
            //用户已加入队伍的队伍
            List<UserTeam> userTeamList = userTeamService.list(queryWrapper);
            //已加入的队伍id
            Set<Long> hasJoinTeamSet = userTeamList.stream().map(UserTeam::getTeamId).collect(Collectors.toSet());
            list.forEach(team -> {
                boolean hasJoin = hasJoinTeamSet.contains(team.getId());
                //返回是否加入某队伍标志，供页面选择性显示按钮
                team.setHasJoin(hasJoin);
            });
        }catch (Exception e){
        }
        //获取已加入某个队伍的人数
        LambdaQueryWrapper<UserTeam> joinNumQw = new LambdaQueryWrapper<>();
        // TODO 在teamIdList为空集合时，加个非空判断 （SQL语法错误）
        joinNumQw.in(UserTeam::getTeamId, teamIdList);
        List<UserTeam> joinNumList = userTeamService.list(joinNumQw);
        //查出某队伍对应的所有用户人数（k->teamId  v->User）
        Map<Long, List<UserTeam>> tidAndUser = joinNumList.stream().collect(Collectors.groupingBy(UserTeam::getTeamId));
        list.forEach(teamUserVO -> teamUserVO.setHasJoinNum(
                tidAndUser.getOrDefault(teamUserVO.getId(), new ArrayList<>())
                        .size()
        ));
        return ResultUtils.success(list);
    }

    @GetMapping("/list/page")
    public BaseResponse<IPage<Team>> pageTeam(TeamQuery teamQuery){
        if (teamQuery == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Team team = new Team();
        BeanUtil.copyProperties(teamQuery, team);
        IPage<Team> page = new Page<>(teamQuery.getPageNum(), teamQuery.getPageSize());
        LambdaQueryWrapper<Team> queryWrapper = new LambdaQueryWrapper<>(team);
        IPage<Team> pageResult = teamService.page(page, queryWrapper);
        return ResultUtils.success(pageResult);
    }

    @PostMapping("/join")
    public BaseResponse<Boolean> joinTeam(@RequestBody TeamJoinRequest teamJoinRequest, HttpServletRequest request){
        if (teamJoinRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        Boolean result = teamService.joinTeam(teamJoinRequest, loginUser);
        return ResultUtils.success(result);
    }

    @PostMapping("/quit")
    public BaseResponse<Boolean> quitTeam(@RequestBody TeamQuitRequest teamQuitRequest, HttpServletRequest request){
        if (teamQuitRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        Boolean result = teamService.quitTeam(teamQuitRequest, loginUser);
        return ResultUtils.success(result);
    }

    /**
     * 查询我创建的队伍
     * @param teamQuery
     * @param request
     * @return
     */
    @GetMapping("/list/my/create")
    public BaseResponse<List<TeamUserVO>> listMyCreateTeam(TeamQuery teamQuery,HttpServletRequest request){
        if (teamQuery == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        teamQuery.setUserId(loginUser.getId());
        List<TeamUserVO> list = teamService.listTeam(teamQuery, true);
        return ResultUtils.success(list);
    }

    @GetMapping("/list/my/join")
    public BaseResponse<List<TeamUserVO>> listMyJoinTeam(TeamQuery teamQuery,HttpServletRequest request){
        if (teamQuery == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        Long userId = loginUser.getId();
        LambdaQueryWrapper<UserTeam> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserTeam::getUserId, userId);
        List<UserTeam> userTeamList = userTeamService.list(queryWrapper);
        Map<Long, List<UserTeam>> listMap = userTeamList.stream().collect(Collectors.groupingBy(UserTeam::getUserId));
        ArrayList<Long> ids = new ArrayList<>(listMap.keySet());
        teamQuery.setIdList(ids);
        List<TeamUserVO> list = teamService.listTeam(teamQuery, true);
        return ResultUtils.success(list);
    }

}
